<%@page contentType="application/json; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.util.zip.*" %>
<%@ page import="java.text.*" %>
<%@ page import="javax.crypto.*" %>
<%@ page import="javax.xml.bind.*" %> 
<%@ page import="javax.xml.transform.stream.StreamSource" %>

<%@ page import="org.team.sdsc.datamodel.*" %>
<%@ page import="org.team.sdsc.datamodel.util.*" %>


<%
     String path = request.getParameter("path");
     String event = request.getParameter("event");
     String arrayName = request.getParameter("array");
     String valid = request.getParameter("valid");

     String prefix = "";
     if (valid != null && valid.equals("false")) {
         prefix = "incomplete-";
     }

     // get the directory for output
     File exportDir = new File(path);

     // get the directory for the image repository
     String root = pageContext.getServletContext().getRealPath("/");
     File rootDir = new File(root, "image-repository");
     
     // get the temporary directory 
     File tmpDir = new File(root+"/WEB-INF/tmp/");
     if (!tmpDir.exists()) {
        tmpDir.mkdirs();
     }
     
     // get the directory of the key
     File keyFile = new File(root+"/WEB-INF/key.txt");
     System.out.println("key file ====> "+keyFile.getAbsolutePath());

     try {

        Network network = NetworkFactory.newInstance();
        Site site = network.getSites().get(0);
	Protocol tv = network.getProtocol(4);

        if (arrayName != null && !arrayName.equals("")) {

	    arrayName = arrayName.substring(5);

            String zipPath = rootDir.getAbsolutePath()+"/"+site.getName()+"/"+event+"/Array"+arrayName;
	    String topName = "CT-"+site.getAbbv()+"-"+event+"-Array"+arrayName;

	    //File exportFile = new File(exportDir, topName+".zip");
            File exportFile = new File(tmpDir, topName+".zip");
	    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(exportFile));

	    System.out.println("=====> export to "+exportFile.getAbsolutePath());
	    System.out.println("=====> root "+root);
	    System.out.println("=====> zip "+zipPath);

            Util.zipDir(zipPath, root, topName, zos);

            List<CameraTrapPhotoCollection> collections = network.getCameraTrapPhotoCollections(site, event, arrayName);	    
	    System.out.println("====> collections = "+collections.size());

            JAXBContext jc = JAXBContext.newInstance( CameraTrapPhotoCollection.class);
            Marshaller m = jc.createMarshaller();

            byte[] readBuffer = new byte[2156];
            int bytesIn = 0;

	    // create xml files
            for (CameraTrapPhotoCollection collection : collections) {

	        File xmlFile = new File(root+"/WEB-INF/tmp/"+collection.getCameraTrap().getName()+".xml");

	        FileOutputStream fos = new FileOutputStream(xmlFile);
                m.marshal(collection, fos);
	        fos.close();

	        FileInputStream fis = new FileInputStream(xmlFile); 
	        ZipEntry anEntry = new ZipEntry(topName+"/data/"+site.getName()+"/"+event+"/Array"+arrayName+"/"+collection.getCameraTrap().getName()+".xml"); 
            
	        //place the zip entry in the ZipOutputStream object 
	        zos.putNextEntry(anEntry); 
            
	        //now write the content of the file to the ZipOutputStream 
	        while((bytesIn = fis.read(readBuffer)) != -1) { 
		   zos.write(readBuffer, 0, bytesIn); 
	        } 
		
	        //close the Stream 
	        fis.close(); 
		xmlFile.delete();
            }

	    //  create manifest file
	    File manifest = new File(root+"/WEB-INF/tmp/manifest.properties");
	    PrintWriter bw = new PrintWriter(new FileWriter(manifest));
	    bw.println("export.site="+site.getName());
	    bw.println("export.event="+event);
            bw.println("export.array="+arrayName);	
            bw.println("export.valid="+valid);	
	    bw.close();
	    
	    FileInputStream fis = new FileInputStream(manifest); 
	    ZipEntry anEntry = new ZipEntry(topName+"/manifest.properties"); 
           
	    //place the zip entry in the ZipOutputStream object 
	    zos.putNextEntry(anEntry); 
            
	    //now write the content of the file to the ZipOutputStream 
	    while((bytesIn = fis.read(readBuffer)) != -1) { 
		zos.write(readBuffer, 0, bytesIn); 
	    } 
		
	    //close the Stream 
	    fis.close(); 
	    manifest.delete();

	    // close zip stream
	    zos.close();	

            DesEncrypter encrypter;
	    if (keyFile.exists()) {
	        // read the key file
	        DataInputStream dis = new DataInputStream(new FileInputStream(keyFile));
                byte[] rawKey = new byte[(int)keyFile.length()];
		dis.readFully(rawKey);
                dis.close();

		//make a key object
                javax.crypto.spec.SecretKeySpec key = new javax.crypto.spec.SecretKeySpec(rawKey, "DES");
	        encrypter = new DesEncrypter(key);
	    } else {
	        // encrypt the package
	        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
	        encrypter = new DesEncrypter(key);

		byte[] rawKey = key.getEncoded();
		DataOutputStream dos = new DataOutputStream(new FileOutputStream(keyFile));
            	dos.write(rawKey, 0, rawKey.length);
            	dos.close();
	    }

	    File encryptFile = new File(exportDir, prefix+topName+".tpk");
	    encrypter.encrypt(new FileInputStream(exportFile), new FileOutputStream(encryptFile));
	    exportFile.delete();

        } else {

            String zipPath = rootDir.getAbsolutePath()+"/"+site.getName()+"/"+event;
	    String topName = "CT-"+site.getAbbv()+"-"+event;

	    //File exportFile = new File(exportDir, topName+".zip");
            File exportFile = new File(tmpDir, topName+".zip");
	    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(exportFile));

	    System.out.println("=====> root "+root);
	    System.out.println("=====> zip "+zipPath);

            Util.zipDir(zipPath, root, topName, zos); 

            List<CameraTrapPhotoCollection> collections = network.getCameraTrapPhotoCollections(site, event);	    
	    System.out.println("====> collections = "+collections.size());

            JAXBContext jc = JAXBContext.newInstance( CameraTrapPhotoCollection.class);
            Marshaller m = jc.createMarshaller();

            byte[] readBuffer = new byte[2156];
            int bytesIn = 0;

            for (CameraTrapPhotoCollection collection : collections) {

	        File xmlFile = new File(root+"/WEB-INF/tmp/"+collection.getCameraTrap().getName()+".xml");

	        FileOutputStream fos = new FileOutputStream(xmlFile);
                m.marshal(collection, fos);
	        fos.close();

		String trapName = collection.getCameraTrap().getName();
		StringTokenizer st = new StringTokenizer(trapName, "-");
		st.nextToken();
		st.nextToken();
		arrayName = st.nextToken();

	        FileInputStream fis = new FileInputStream(xmlFile); 
	        ZipEntry anEntry = new ZipEntry(topName+"/data/"+site.getName()+"/"+event+"/Array"+arrayName+"/"+collection.getCameraTrap().getName()+".xml"); 
            
	        //place the zip entry in the ZipOutputStream object 
	        zos.putNextEntry(anEntry); 
            
	        //now write the content of the file to the ZipOutputStream 
	        while((bytesIn = fis.read(readBuffer)) != -1) { 
		   zos.write(readBuffer, 0, bytesIn); 
	        } 
		
	        //close the Stream 
	        fis.close(); 
		xmlFile.delete();
            }

	    //  create manifest file
	    File manifest = new File(root+"/WEB-INF/tmp/manifest.properties");
	    PrintWriter bw = new PrintWriter(new FileWriter(manifest));
	    bw.println("export.site="+site.getName());
	    bw.println("export.event="+event);
            bw.println("export.valid="+valid);	
	    bw.close();
	    
	    FileInputStream fis = new FileInputStream(manifest); 
	    ZipEntry anEntry = new ZipEntry(topName+"/manifest.properties"); 
           
	    //place the zip entry in the ZipOutputStream object 
	    zos.putNextEntry(anEntry); 
            
	    //now write the content of the file to the ZipOutputStream 
	    while((bytesIn = fis.read(readBuffer)) != -1) { 
		zos.write(readBuffer, 0, bytesIn); 
	    } 
		
	    //close the Stream 
	    fis.close(); 
	    manifest.delete();

	    zos.close();	

            DesEncrypter encrypter;
	    if (keyFile.exists()) {
	        // read the key file
	        DataInputStream dis = new DataInputStream(new FileInputStream(keyFile));
                byte[] rawKey = new byte[(int)keyFile.length()];
		dis.readFully(rawKey);
                dis.close();

		//make a key object
                javax.crypto.spec.SecretKeySpec key = new javax.crypto.spec.SecretKeySpec(rawKey, "DES");
	        encrypter = new DesEncrypter(key);
	    } else {
	        // encrypt the package
	        SecretKey key = KeyGenerator.getInstance("DES").generateKey();
	        encrypter = new DesEncrypter(key);

		byte[] rawKey = key.getEncoded();
		DataOutputStream dos = new DataOutputStream(new FileOutputStream(keyFile));
            	dos.write(rawKey, 0, rawKey.length);
            	dos.close();
	    }

	    File encryptFile = new File(exportDir, prefix+topName+".tpk");
	    encrypter.encrypt(new FileInputStream(exportFile), new FileOutputStream(encryptFile));
	    exportFile.delete();

	}
 

        network.close();

	out.println("{ success : true } ");

    } catch (Exception ex) {
        ex.printStackTrace();
	out.println("{ success : false, message: '"+ex.getMessage()+"' } ");
    }
%>